/*
   PTZSnapshot.java
   (C) 2007 - Michael Ocean - Boston University

  This work is a part of the larger snBench project.  Information
  can be found at: http://csr.bu.edu/snbench

  This program is free software; you can redistribute it and/or
  modify it under the terms of Version 2 of the GNU General Public 
  License.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package sxe.core.ptzctl;

import snobject.snInteger;
import snobject.snNil;
import snobject.snObject;
import snobject.snObjectArgList;
import snobject.snSensor;
import step.EvaluationFailure;
import step.FunctionWrapper;
import step.exceptions.ResourceUnavailableException;
import sxe.sensors.GenericSensor;
import sxe.sensors.PTZSensor;
import sxe.sensors.SensorDetector;

public class PTZSnapshot extends FunctionWrapper {

	@Override
	public snObject Call(snObjectArgList argv) throws EvaluationFailure,
			ClassCastException, ArrayIndexOutOfBoundsException,
			ResourceUnavailableException {

		/* remove the sensor from the arguments */
		snSensor sens = argv.popSensor();
		
		String sSensorID = sens.getSensorID();
		String sSensorType = sens.getSensorType();
		String sFormat = "";

		GenericSensor gs = SensorDetector.GetDevice(sSensorID, sSensorType);
		if(gs==null){
			System.err.println("Could not locate a sensor with ID '" + sSensorID + "' of type " + sSensorType );
			throw new EvaluationFailure(this.expnode,"Couldn't get sensor " + sSensorID);
		}

		if(!(gs instanceof PTZSensor)){
			System.err.println("Sensor " + sSensorID + "is not of type PTZSensor");
			throw new EvaluationFailure(this.expnode,"Sensor " + sSensorID + "is not of type PTZSensor");
		}
		if(! gs.getType().equals(GenericSensor.TYPE_IMAGE_PTZ))
		{
			System.err.println("Sensor " + sSensorID + "is not a PTZ Sesnor");
			throw new EvaluationFailure(this.expnode,"Sensor " + sSensorID + "is not a PTZ Sensor");
		}

		Integer iPan = null,iTilt = null,iZoom = null;
				
		snObject o = argv.popObject();
		if(!snNil.NIL.equals(o))
			iPan = ((snInteger)o).getInt();
		o = argv.popObject();
		if(!snNil.NIL.equals(o))
			iTilt = ((snInteger)o).getInt();
		o = argv.popObject();
		if(!snNil.NIL.equals(o))
			iZoom = ((snInteger)o).getInt();		
		
		if(iPan!=null){
			if((iPan >180)||(iPan < -180)){
				System.err.println("Specified pan amount " + iPan + " exceeds range of [-180..180]");
				throw new EvaluationFailure(this.expnode,"Specified pan amount " + iPan + " exceeds range of [-180..180]");
			}
			sFormat.concat("&pan=" + iPan.toString());
		}
		if(iTilt!=null){
			if((iTilt >180)||(iTilt < -180)){
				System.err.println("Specified pan amount " + iTilt + " exceeds range of [-180..180]");
				throw new EvaluationFailure(this.expnode,"Specified tilt amount " + iTilt + " exceeds range of [-180..180]");
			}
			sFormat.concat("&tilt=" + iTilt.toString());
		}
		if(iZoom!=null){
			if((iZoom >9999)||(iZoom < 1)){
				System.err.println("Specified pan amount " + iZoom + " exceeds range of [0..9999]");
				throw new EvaluationFailure(this.expnode,"Specified zoom amount " + iZoom + " exceeds range of [0..9999]");
			}
			sFormat.concat("&zoom=" + iZoom.toString());
		}
		
		/* grab a frame from the framegrabber */
		snObject snRet = null;
		
		PTZSensor ptz = (PTZSensor) gs; 
		snRet = ptz.getData(sFormat);
				
		if(snRet.equals(snNil.NIL))
			throw new EvaluationFailure(this.expnode,"Failed to pan camera specified amount.");
		return snRet;

	}

}